import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useBlockchainStore = defineStore('blockchain', () => {
  // 状态
  const isConnected = ref(false)
  const provider = ref(null)
  const signer = ref(null)
  const account = ref('')
  const network = ref(null)
  const contracts = ref({
    accessControl: null,
    teaBatch: null,
    traceabilitySystem: null
  })
  const loading = ref(false)
  const error = ref('')

  // 计算属性
  const isWeb3Available = computed(() => {
    return typeof window !== 'undefined' && typeof window.ethereum !== 'undefined'
  })

  const networkName = computed(() => {
    if (!network.value) return ''
    
    const networks = {
      1: 'Ethereum Mainnet',
      3: 'Ropsten Testnet',
      4: 'Rinkeby Testnet',
      5: 'Goerli Testnet',
      11155111: 'Sepolia Testnet',
      31337: 'Hardhat Local'
    }
    
    return networks[network.value.chainId] || `Network ${network.value.chainId}`
  })

  // 方法
  const connectWallet = async () => {
    if (!isWeb3Available.value) {
      error.value = '请安装 MetaMask 或其他 Web3 钱包'
      return { success: false, message: error.value }
    }

    loading.value = true
    error.value = ''

    try {
      // 请求连接钱包
      const accounts = await window.ethereum.request({
        method: 'eth_requestAccounts'
      })

      if (accounts.length === 0) {
        throw new Error('未选择任何账户')
      }

      // 动态导入 ethers
      const { ethers } = await import('ethers')
      
      // 创建 provider 和 signer
      provider.value = new ethers.providers.Web3Provider(window.ethereum)
      signer.value = provider.value.getSigner()
      account.value = accounts[0]
      network.value = await provider.value.getNetwork()
      isConnected.value = true

      console.log('钱包连接成功:', {
        account: account.value,
        network: networkName.value
      })

      // 监听账户变化
      window.ethereum.on('accountsChanged', handleAccountsChanged)
      window.ethereum.on('chainChanged', handleChainChanged)

      return { success: true, account: account.value }

    } catch (err) {
      console.error('钱包连接失败:', err)
      error.value = err.message || '钱包连接失败'
      return { success: false, message: error.value }
    } finally {
      loading.value = false
    }
  }

  const disconnectWallet = () => {
    isConnected.value = false
    provider.value = null
    signer.value = null
    account.value = ''
    network.value = null
    contracts.value = {
      accessControl: null,
      teaBatch: null,
      traceabilitySystem: null
    }
    error.value = ''

    // 移除事件监听器
    if (window.ethereum) {
      window.ethereum.removeListener('accountsChanged', handleAccountsChanged)
      window.ethereum.removeListener('chainChanged', handleChainChanged)
    }
  }

  const handleAccountsChanged = (accounts) => {
    if (accounts.length === 0) {
      disconnectWallet()
    } else {
      account.value = accounts[0]
      console.log('账户已切换:', account.value)
    }
  }

  const handleChainChanged = () => {
    // 网络变化时重新加载页面
    window.location.reload()
  }

  const switchNetwork = async (chainId) => {
    if (!isConnected.value) {
      throw new Error('钱包未连接')
    }

    try {
      await window.ethereum.request({
        method: 'wallet_switchEthereumChain',
        params: [{ chainId: `0x${chainId.toString(16)}` }]
      })
    } catch (switchError) {
      // 如果网络不存在，尝试添加
      if (switchError.code === 4902) {
        throw new Error('请手动添加此网络到您的钱包')
      } else {
        throw switchError
      }
    }
  }

  const initializeContracts = async (contractAddresses) => {
    if (!isConnected.value || !signer.value) {
      throw new Error('钱包未连接')
    }

    try {
      const { ethers } = await import('ethers')

      // 合约 ABI (简化版本)
      const ACCESS_CONTROL_ABI = [
        "function registerUser(address userAddress, uint8 userRole) external",
        "function hasRole(address userAddress, uint8 requiredRole) external view returns (bool)",
        "function getUserRole(address userAddress) external view returns (uint8)"
      ]

      const TEA_BATCH_ABI = [
        "function createBatch(string memory batchId, string memory name, string memory variety) external returns (uint256)",
        "function getBatchInfo(uint256 batchTokenId) external view returns (tuple)"
      ]

      if (contractAddresses.accessControl) {
        contracts.value.accessControl = new ethers.Contract(
          contractAddresses.accessControl,
          ACCESS_CONTROL_ABI,
          signer.value
        )
      }

      if (contractAddresses.teaBatch) {
        contracts.value.teaBatch = new ethers.Contract(
          contractAddresses.teaBatch,
          TEA_BATCH_ABI,
          signer.value
        )
      }

      console.log('智能合约初始化成功')
      return true

    } catch (err) {
      console.error('合约初始化失败:', err)
      throw err
    }
  }

  const getBalance = async () => {
    if (!isConnected.value || !provider.value) {
      throw new Error('钱包未连接')
    }

    try {
      const balance = await provider.value.getBalance(account.value)
      const { ethers } = await import('ethers')
      return ethers.utils.formatEther(balance)
    } catch (err) {
      console.error('获取余额失败:', err)
      throw err
    }
  }

  const sendTransaction = async (to, value, data = '0x') => {
    if (!isConnected.value || !signer.value) {
      throw new Error('钱包未连接')
    }

    try {
      const { ethers } = await import('ethers')
      
      const tx = await signer.value.sendTransaction({
        to,
        value: ethers.utils.parseEther(value.toString()),
        data
      })

      console.log('交易发送成功:', tx.hash)
      return tx
    } catch (err) {
      console.error('交易发送失败:', err)
      throw err
    }
  }

  const signMessage = async (message) => {
    if (!isConnected.value || !signer.value) {
      throw new Error('钱包未连接')
    }

    try {
      const signature = await signer.value.signMessage(message)
      console.log('消息签名成功')
      return signature
    } catch (err) {
      console.error('消息签名失败:', err)
      throw err
    }
  }

  // 初始化检查是否已经连接
  const checkConnection = async () => {
    if (!isWeb3Available.value) return false

    try {
      const accounts = await window.ethereum.request({
        method: 'eth_accounts'
      })

      if (accounts.length > 0) {
        await connectWallet()
        return true
      }
    } catch (err) {
      console.error('检查连接状态失败:', err)
    }

    return false
  }

  return {
    // 状态
    isConnected,
    provider,
    signer,
    account,
    network,
    contracts,
    loading,
    error,

    // 计算属性
    isWeb3Available,
    networkName,

    // 方法
    connectWallet,
    disconnectWallet,
    switchNetwork,
    initializeContracts,
    getBalance,
    sendTransaction,
    signMessage,
    checkConnection
  }
})